package com.heima.search.service.impl;

import com.heima.common.exception.CustException;
import com.heima.feigns.BehaviorFeign;
import com.heima.model.behavior.pojos.ApBehaviorEntry;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.HistorySearchDTO;
import com.heima.model.search.dtos.UserSearchDTO;
import com.heima.model.search.pojos.ApUserSearch;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.service.ApUserSearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author huan
 * @serial 每天一百行, 致敬未来的自己
 * @Description
 */
@Service
@Slf4j
@EnableAsync
public class ApUserSearchServiceImpl implements ApUserSearchService {
    @Autowired
    MongoTemplate mongoTemplate;
    @Autowired
    BehaviorFeign behaviorFeign;

    /**
     * 保存用户搜索历史记录
     *
     * @param dto
     */
    @Override
    @Async("taskExecutor")
    public void insert(UserSearchDTO dto) {
        //1 参数检查
        String searchWords = dto.getSearchWords();
        Integer entryId = dto.getEntryId();
        //2 查询行为实体
        ResponseResult<ApBehaviorEntry> behaviorResponse = behaviorFeign.findByUserIdOrEquipmentId(entryId, dto.getEquipmentId());
        if (!behaviorResponse.checkCode()) {
            CustException.cust(AppHttpCodeEnum.REMOTE_SERVER_ERROR);
        }
        ApBehaviorEntry apBehaviorEntry = behaviorResponse.getData();
        if (apBehaviorEntry == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        log.info("ApUserSearchServiceImpl insert entryId:{}, searchWords:{}", entryId, searchWords);
        //3 查询当前用户搜索的关键词是否存在
        Query query = Query.query(Criteria.where("entryId")
                .is(apBehaviorEntry.getId()).and("keyword").is(searchWords));
        ApUserSearch apUserSearch = mongoTemplate.findOne(query, ApUserSearch.class);
        //3.1 存在则更新最新时间，更新状态
        if (apUserSearch != null) {
            //apUserSearch.setCreatedTime(new Date());
            //mongoTemplate.save(apUserSearch);
            mongoTemplate.updateMulti(query, new Update().set("createdTime", new Date()), ApUserSearch.class);
            return;
        }
        //3.2 不存在则新增
        apUserSearch = new ApUserSearch();
        apUserSearch.setCreatedTime(new Date());
        apUserSearch.setEntryId(apBehaviorEntry.getId());
        apUserSearch.setKeyword(searchWords);
        mongoTemplate.save(apUserSearch);
    }

    @Override
    public ResponseResult findUserSearch(UserSearchDTO dto) {
        if (dto.getMinBehotTime() == null) {
            dto.setMinBehotTime(new Date());
        }
        //获取当前用户
        ApUser user = AppThreadLocalUtils.getUser();
        //远程调用查询行为实体
        ResponseResult<ApBehaviorEntry> result = behaviorFeign.findByUserIdOrEquipmentId(user == null ? null : user.getId(), dto.getEquipmentId());
        if (!result.checkCode()) {
            CustException.cust(AppHttpCodeEnum.SERVER_ERROR, result.getErrorMessage());
        }
        //获取实体对象
        ApBehaviorEntry behaviorEntry = result.getData();
        if (behaviorEntry == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //根据条件查询mongoDB,倒序取前10
        List<ApUserSearch> searchList = mongoTemplate.find(Query.query(Criteria.where("entryId").is(behaviorEntry.getId())
                        .and("createdTime").lt(dto.getMinBehotTime()))
                .with(Sort.by(Sort.Direction.DESC, "createdTime"))
                .limit(10), ApUserSearch.class);
        return ResponseResult.okResult(searchList);
    }

    @Override
    public ResponseResult deleteUserSearch(HistorySearchDTO dto) {
        if (dto.getId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApUser user = AppThreadLocalUtils.getUser();
        ResponseResult<ApBehaviorEntry> behaviorEntryResult = behaviorFeign.findByUserIdOrEquipmentId(user == null ? null : user.getId(), dto.getEquipmentId());
        if (!behaviorEntryResult.checkCode()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.REMOTE_SERVER_ERROR, "远程调用行为服务失败");
        }
        ApBehaviorEntry behaviorEntry = behaviorEntryResult.getData();
        if (behaviorEntry == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "行为实体数据不存在");
        }
        //删除mongoDB对应数据
        mongoTemplate.remove(Query.query(Criteria.where("id").is(dto.getId())
                .and("entryId").is(behaviorEntry.getId())), ApUserSearch.class);
        return ResponseResult.okResult();
    }
}
